    #ifndef MDENSE_H
    #define MDENSE_H
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <ctime>
    #include <boost/timer.hpp>
    #include "MDense.h"
    
    
    using namespace boost;
    using namespace std;
    
    template <typename T>
    class MDense
    {
	protected:
        //attributs
		int lignes_;
		int colonnes_;
		vector <vector <T> > donnees_;
		
		
    public:
		MDense<T>( int nb_lignes, int nb_colonnes);// constructeur par parametres
		//~MDense<T>();
		//methodes
		void readMDense();
		void printMDense();
		void GEMV(const vector <T>& u, vector <T> v,char* forme);
		//getteurs
		int ObtenirLignes();
		int ObtenirColonnes();
		T ObtenirDonnees(int i, int j);
		//setteur
		void ModifierDonees(int, int j, T k);
    
    };
    
    
    /****************************************************************************
    * Fonction: MDense<T>::MDense()
    * Description: Constructeur par paramètres
    * Paramètres: - int nb_lignes: nombre de lignes
    *             - int nb-colonnes: nombre de colones
    *
    * Retour: aucun
    ****************************************************************************/
    template <typename T>
    MDense<T>::MDense(int nb_lignes, int nb_colonnes):donnees_(nb_lignes,vector<T>(nb_colonnes))
    {
		lignes_ = nb_lignes;
    	colonnes_ = nb_colonnes;
    	for(int i=0; i<lignes_; i++)
    	{
			for(int j=0; j<colonnes_; j++)
			{
				donnees_[i][j]=0;
			}
			donnees_[i][i]=1;
		}
    }
    /****************************************************************************
    //* Fonction: MDense<T>::~MDense()
    //* Description: Destructeur
    //* Paramètres: aucun
    //* Retour: aucun
    //****************************************************************************/
    //template <typename T>
    //MDense<T>::~MDense()
    //{
		//for(int i=0; i<lignes_;i++)
		//{
			//delete[] donnees_[i];
		//}
		//delete[] donnees_;
	//}
    /****************************************************************************
    * Fonction: MDense::readMDense()
    * Description: lit les éléments d'une matrice
    * Paramètres: aucun
    * Retour: aucun
    ****************************************************************************/
    template <typename T>
    void MDense<T>::readMDense()
    {
		for(int i=0; i< lignes_; i++)
		{
			for (int j=0; j<colonnes_; j++)
				cin >> donnees_[i][j];
		}
    }
    /****************************************************************************
    * Fonction: MDense<T>::printMDense()
    * Description: affiche les éléments d'une matrice
    * Paramètres: aucun
    * Retour: aucun
    ****************************************************************************/
    template <typename T>
    void MDense<T>::printMDense()
    {
    for(int i=0; i< lignes_; i++)
    {
    for (int j=0; j<colonnes_; j++)
    cout<< donnees_[i][j]<<" ";
    cout <<" " << endl;
    }
    }
    /****************************************************************************
    * Fonction: MDense<T>::GEMV()
    * Description: effectue le produit matrice vecteur
    * Paramètres: le vecteur multiplié u, le vecteur resulat v, la forme de la matrice
    * Retour: aucun
    ****************************************************************************/
    template <typename T>
    void MDense<T>::GEMV(const vector <T>& u, vector <T> v,char* forme)
    {	
		//parametres chronometre
		int f_compteur=1;
		double temps_moy=0.0000; //temps moyen
	
		//for(int compteur=0;compteur<f_compteur;compteur++)
		//{
			//debut chrono
			timer t;
			t.elapsed();
			for(int i=0; i< lignes_; i++)
			{
				for (int k=0; k<colonnes_; k++)
				{
					v[i]=donnees_[i][k]*u[k]+v[i];
				}
				//cout<<"pour dense : v["<<i<<"]="<<v[i]<<endl;
				//fin chrono
				temps_moy=temps_moy+t.elapsed();
			}
		//}
		temps_moy = temps_moy/((double)f_compteur);
		
		// ouverture fichier en ecriture seule
		ofstream fichier("dense_cpp.csv", ios::out | ios::app);
		if(fichier)
		{
			fichier << lignes_ << ";" << colonnes_ << ";" << forme << ";" << temps_moy << endl;
			fichier.close();
		}
    }
    /****************************************************************************
    * Fonction: MDense<T>::ObtenirLignes()
    * Description: retourne le nombre de lignes d'une matrice
    * Paramètres: aucun
    * Retour: int nombre de lignes
    ****************************************************************************/
    template <typename T>
    int MDense<T>::ObtenirLignes()
    {
    return lignes_;
    }
    /****************************************************************************
    * Fonction: MDense<T>::ObtenirColonnes()
    * Description: retourne le nombre de colonnes d'une matrice
    * Paramètres: aucun
    * Retour: int nombre de colonnes
    ****************************************************************************/
    template <typename T>
    int MDense<T>::ObtenirColonnes()
    {
    return colonnes_;
    }
    /****************************************************************************
    * Fonction: MDense<T>::ObtenirDonnees()
    * Description: retourne la valeur en [i][j] la matrice 
    * Paramètres: - int i numero de la ligne correspondante
    *             - int j numero de la colonne correspondante
    * Retour: T donnee_[i][j]
    ****************************************************************************/
    template <typename T>
    T MDense<T>::ObtenirDonnees(int i, int j)
    {
		return donnees_[i][j];
	}
	/****************************************************************************
    * Fonction: MDense<T>::ModifierDonnees()
    * Description: retourne la valeur d'une coordonnee de la matrice 
    * Paramètres: - int i numero de la ligne correspondante
    *             - int j numero de la colonne correspondante
    *             - T k valeur dde la matrice en [i][j]
    * Retour: aucun
    ****************************************************************************/
	template <typename T>
    void MDense<T>::ModifierDonees(int i, int j,T k)
    {
		donnees_[i][j]=k;
	}
    # endif 

